package com.ebupt.migu.fineoperationactivitymonitor.common.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.IOUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author liuyangyang@e-byte.com
 * @description: TODO
 * @date 2023/4/24 10:40
 */
@Slf4j
public class HttpsUtils {
    private static PoolingHttpClientConnectionManager connMgr;
    private static final int MAX_TIMEOUT = 10000;
    /**
     * 线程安全的
     */
    private static CloseableHttpClient httpClient;

    static {
        // 设置连接池
        connMgr = new PoolingHttpClientConnectionManager();
        connMgr.setMaxTotal(500);
        connMgr.setDefaultMaxPerRoute(10);

        RequestConfig.Builder configBuilder = RequestConfig.custom();
        // 设置链接超时
        configBuilder.setConnectTimeout(MAX_TIMEOUT);
        // 设置读取超时
        configBuilder.setSocketTimeout(MAX_TIMEOUT);
        // 设置从连接池获取连接实例的超时
        configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);

        httpClient = HttpClients.custom().setConnectionManager(connMgr)
            .setSSLSocketFactory(getSslConnectionSocketFactory()).build();
    }

    public static String doGetRequest(String url, Map<String, Object> map) {
        List<NameValuePair> params = new ArrayList<>();
        Set<Map.Entry<String, Object>> set = map.entrySet();
        for (Map.Entry<String, Object> entry : set) {
            NameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), (String)entry.getValue());
            params.add(nameValuePair);
        }
        String apiURL = url;
        log.info("访问URL：{}，访问参数：{}", url, map);
        String result = null;
        try {
            String str = EntityUtils.toString(new UrlEncodedFormEntity(params, Consts.UTF_8));
            HttpGet httpGet = new HttpGet(apiURL + "?" + str);
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                InputStream inputStream = entity.getContent();
                result = IOUtils.toString(inputStream, "UTF-8");
            }
            EntityUtils.consume(entity);
        } catch (IOException io) {
            throw new RuntimeException("调用远程URL连接失败", io);
        }
        log.info("访问URL：{}， 访问结果：{}", url, result);
        return result;
    }

    /**
     * HTTPS请求忽略SSL证书
     *
     * @return
     */
    private static SSLConnectionSocketFactory getSslConnectionSocketFactory() {
        try {
            TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
            return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
        } catch (Exception e) {
            log.error("HTTPS请求设置忽略SSL证书出错：{}", e.getMessage());
            return null;
        }
    }
}
